package com.xframe.xdal.core.domain;

import com.xframe.xdal.core.DataBaseAccess;
import com.xframe.xdal.core.exception.DalFrameException;
import com.xframe.xdal.core.model.*;
import com.xframe.xdal.core.model.mapping.ITableInfo;
import com.xframe.xdal.core.model.page.IPagerModel;
import com.xframe.xdal.core.tran.IDbTransaction;

import java.util.Collection;

/**
 * 领域模型的基础Repository接口
 * REPOSITORY
 * @author xufeng
 * @version 1.0
 * @date 2023-03-10
 */
public interface  IRepository {

    /**
     * 初始化
     *
     * @return
     */
    void init();
    /**
     * 获得一个数据访问
     *
     * @return
     */
    DataBaseAccess getDataBaseAccess();
    /**
     * 创建一个行的事务对象
     *
     * @return
     */
    IDbTransaction beginTransaction();
    /**
     * 创建一个行的事务对象
     * @param level 事务隔离级别
     * @return
     */
    IDbTransaction beginTransaction(int level);
    /**
     * 提交一个事务
     */
    void commitTran();
    /**
     * 回滚事务
     */
    void rollBackTran();

    /**
     * 根据类型查找对象
     * @param dataType 数据类型
     * @param findOptions 查询条件
     *
     * @return 查询结果集
     */
    <T> T queryModle(Class<?> dataType,FindOptions findOptions);

    /**
     * 创建一个新的对象到数据库
     * @param model 被保存的对象
     *
     * @return 受影响的行数
     */
    Integer createNew(IModel model) throws DalFrameException;
    /**
     * 创建一个新的对象到数据库
     * @param model 被保存的对象
     * @param tableInfo 数据表结构
     *
     * @return 受影响的行数
     */
    Integer createNew(IModel model, ITableInfo tableInfo) throws DalFrameException;


    /**
     * 创建一个新的对象到数据库，存在修改，不存在新增
     * @param model 被保存的对象
     * @param tableInfo 数据表结构
     *
     * @return
     */
    Integer save(IModel model,ITableInfo tableInfo) throws DalFrameException;


    /**
     * 创建一个新的对象到数据库，存在修改，不存在新增
     * @param model 被保存的对象
     * @param tableInfo 数据表结构
     *
     * @return
     */
    Integer createOrUpdate(IModel model,ITableInfo tableInfo) throws DalFrameException;

    /**
     * 修改一个对象到数据库
     * @param model 被保存的对象
     * @param tableInfo 数据表结构
     *
     * @return
     */
    Integer update(IModel model,ITableInfo tableInfo) throws DalFrameException;


    /**
     * 修改一个对象到数据库
     * @param model 被保存的对象
     * @param tableInfo 数据表结构
     * @param updateAttr update语句参数
     * @return
     */
    Integer update(IModel model, ITableInfo tableInfo, UpdateAttr updateAttr) throws DalFrameException;

    /**
     * 根据ID删除一个对象
     * @param id 对象ID
     * @param tableInfo 数据表结构
     *
     * @return
     */
    Integer deleteById(Object id, ITableInfo tableInfo) throws DalFrameException;

    /**
     * 删除一个对象
     * @param model 被保存的对象
     * @param tableInfo 数据表结构
     *
     * @return
     */
    Integer delete(IModel model,ITableInfo tableInfo) throws DalFrameException;




    /**
     * 判断一个对象是否存在（AK）
     * @param model 被保存的对象
     *
     * @return
     */
    boolean exists(IModel model) throws DalFrameException;
    /**
     * 判断一个对象是否存在（AK）
     * @param model 被保存的对象
     * @param tableInfo 数据表结构
     *
     * @return
     */
    boolean exists(IModel model, ITableInfo tableInfo) throws DalFrameException;

    /**
     * 分页查询
     * @param dataType 被查询的数据类型
     * @param tableInfo 数据表结构
     * @param findOptions 查询设置对象
     *
     * @return IPagerModel分页数据
     */
    <T> IPagerModel<T> queryModleByPage(Class<?> dataType, ITableInfo tableInfo, FindOptions findOptions);

    /**
     * 不分页的查询
     * @param dataType 被查询的数据类型
     * @param tableInfo 数据表结构
     * @param findOptions 查询设置对象
     *
     * @return 查询的集合
     */
    <T> T queryModle(Class<?> dataType, ITableInfo tableInfo,FindOptions findOptions);
    /**
     * 获得一个指定的对象
     * @param dataType 返回的数据类型
     * @param tableInfo 数据表结构
     * @param id id
     * @param refNames 关系名称列表
     *
     * @return T的实例对象
     */
    <T> T findByPK(Class<?> dataType,Object id,ITableInfo tableInfo,String... refNames);

    /**
     * 获得一个完整的对象
     * @param dataType 返回的数据类型
     * @param tableInfo 数据表结构
     * @param id id
     *
     * @return T的实例对象
     */
    <T> T findByPK(Class<?> dataType,Object id,ITableInfo tableInfo);


    /**
     * 根据关键字来获得一个实体对象
     * @param dataType 返回的数据类型
     * @param code 关键字
     * @param tableInfo 表结构
     * @param refNames 引用关系列表
     * @return T的实例对象
     */
    <T> T findbyAk(Class<?> dataType,Object code,ITableInfo tableInfo,String... refNames);

    /**
     * 根据多个关键字来获得一个实体对象
     * @param dataType 返回的数据类型
     * @param codes 关键字列表
     * @param tableInfo 表结构
     * @param refNames 引用关系列表
     * @return T的实例对象
     */
    <T> T findbyAk(Class<?> dataType,Collection<Object> codes,ITableInfo tableInfo,String... refNames);


    /**
     * 根据类型来获关键字来获得一个完整对象
     * @param dataType 返回的数据类型
     * @param code 关键字
     *
     * @return T的实例对象
     */
    <T> T findbyAk(Class<?> dataType,Object code);
    /**
     * 根据条件来删除数据
     * @param tableInfo 表结构
     * @param whereCollection 条件
     *
     * @return 受影响的行数
     */
    Integer deleteMany(ITableInfo tableInfo, ConditionValueCollection whereCollection);


    /**
     * 批量添加数据
     * @param dataType 数据类型
     * @param collection 数据列表
     * @param maxDataLength 单次提交的数据量
     *
     * @return 受影响的行数
     */
    <E> Integer batchCreate(Class<?> dataType, Collection<E> collection, Integer maxDataLength);


    /**
     * 批量保存 不存在insert 存在oracle 走update mySql 走的删除在insert
     * @param dataType 数据类型
     * @param collection 数据列表
     * @param maxDataLength 单次提交的数据量
     *
     * @return 受影响的行数
     */
    <E> Integer batchSave(Class<?> dataType, Collection<E> collection, Integer maxDataLength);

    /**
     * 批量保存(存在则修改)
     *
     * @param dataType 数据类型
     * @param collection 被操作的结果
     *
     * @param <E>
     * @return 操作结果
     * @throws DalFrameException 异常
     */
    <E> Integer batchSave(Class<?> dataType, Collection<E> collection);
    /**
     * 删除后创建数据（适用于多对对关系变）
     * @param tableInfo 表结构
     * @param dataType 数据类型
     * @param keyName 查询的属性名称
     * @param keyValue 查询的属性值
     * @param collection 数据列表
     * @param maxDataLength 单次提交的数据量
     *
     * @return 受影响的行数
     */
    <E> DelAndSaveRes deleteAndSave(ITableInfo tableInfo, Class<?> dataType,String keyName, Object keyValue, Collection<E> collection, Integer maxDataLength) throws DalFrameException;

    /**
     * 删除后创建数据（适用于多对对关系变）
     * @param tableInfo 表结构
     * @param setWrapCollection set子句
     * @param whereCollection 批量where条件
     *
     * @return 受影响的行数
     */
    Integer updateMany(ITableInfo tableInfo, SetWrapCollection setWrapCollection,
                              ConditionValueCollection whereCollection);

}
